/*********************************************************************
 *    Project Name : tscp-platform
 *    Package Name : com.tscp.platform.service.es
 *    Create  Time : 2021/5/25 17:06
 *    =============================================================
 *    (C) Copyright Trustcro Information Technology Co., Ltd.
 *          Corporation 2018-2021 All Rights Reserved.
 *
 *	  【注意： 本内容仅限于长沙信立诚医药科技有限公司内部使用，禁止转发】
 **********************************************************************/
package com.trust.pams.service.es;

import com.alibaba.fastjson.JSON;
import com.chasonx.common.model.PageResult;
import com.chasonx.common.util.StringKit;

import com.trust.pams.dto.PamsQuoteDto;
import com.trust.pams.model.Tree.Tree;
import com.trust.pams.model.query.PamsQuoteQuery;
import com.trust.pams.model.query.PamsSvnQuery;
import com.trust.pams.query.BaseQuery;
import com.trust.pams.util.DataUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Project : tscp-platform
 * @Author : Chasonx<zc.x>
 * @CreateTime : 2021/5/25 17:06
 * @Desc :
 * @Version : 1.0
 */
@Component
public class EsQuery {

    private static final Logger log = LoggerFactory.getLogger(EsQuery.class);

    private static RestHighLevelClient restHighLevelClient;

    private static final String INDEX = "es_pams";

    private static final String TYPES_Qe="pams_quote";

    @Autowired
    public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
        EsQuery.restHighLevelClient = restHighLevelClient;
    }

    public static PageResult<PamsQuoteDto> queryQuote(PamsQuoteQuery pamsQuoteQuery){
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
            QueryStringQueryBuilder keyWord = QueryBuilders.queryStringQuery(pamsQuoteQuery.getProjectName()).type(MultiMatchQueryBuilder.Type.PHRASE);
            if(DataUtil.isNotEmpty(pamsQuoteQuery.getProjectName())){
                queryBuilder = QueryBuilders.boolQuery().must(keyWord);
            }
        PageResult<PamsQuoteDto> pageData = getResponseData(INDEX , TYPES_Qe , pamsQuoteQuery , queryBuilder , PamsQuoteDto.class);
        return pageData;
    }

    public static List<Tree> querySvn(PamsSvnQuery svnQuery ){
        QueryStringQueryBuilder keyWord = QueryBuilders.queryStringQuery(svnQuery.getProjectGuid());
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        if(DataUtil.isNotEmpty(svnQuery.getProjectGuid())){
            queryBuilder = QueryBuilders.boolQuery().must(keyWord);
        }
        PageResult<Tree> pageData = getResponseData(INDEX , TYPES_Qe , svnQuery , queryBuilder , Tree.class);
        return pageData.getData();
    }

    private static <T> PageResult<T> getResponseData(String index, String types, BaseQuery baseQuery, QueryBuilder queryBuilder, Class<T> cls){
        SearchRequest request = new SearchRequest();
        request.indices(index + "__" + types);

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(queryBuilder)
                .from( (baseQuery.getPageNumber() - 1) * baseQuery.getPageSize() )
                .size(baseQuery.getPageSize());
        sourceBuilder.timeout(new TimeValue(60 , TimeUnit.SECONDS));

        request.source(sourceBuilder);

        PageResult<T> pageData = PageResult.get(baseQuery);
        try{
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT );
            SearchHits hits = response.getHits();
            SearchHit[] hit = response.getHits().getHits();

            pageData.setTotalRow( hits.getTotalHits().value );

            List<T> listData = new ArrayList<>();
            for(SearchHit h : hit){
                if(null != h.getSourceAsString()){
                    listData.add(JSON.parseObject(h.getSourceAsString() , cls));
                }
            }
            pageData.setData(listData);
            log.info("rquest data : {}", listData.size());
        }catch (Exception e){
            log.error("getResponseData exception => " , e);
        }

        return pageData;
    }

  /*  private static final String F_LAN = "language";
    private static final String F_V = "version";
    private static final String INDEX = "tscp-platform-mongo";
    private static final String TYPES_WD = "wd_dd";
    private static final String TYPES_MD = "md_llt";

    @Autowired
    public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
        EsQuery.restHighLevelClient = restHighLevelClient;
    }

    public static PageResult<WdDd> pageQueryWhoDrug(WhoDrugQuery query){
        MatchQueryBuilder language = QueryBuilders.matchQuery(F_LAN , query.getLanguage());
        MatchQueryBuilder version = QueryBuilders.matchQuery(F_V , query.getVersion());
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(language)
                .must(version);

        if(StringKit.notBlank(query.getRegexName())){
            //MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(query.getRegexName() ,"drugName")
            //                                      .type(MultiMatchQueryBuilder.Type.BEST_FIELDS);
            MatchQueryBuilder regexName = QueryBuilders.matchQuery("drugName" , query.getRegexName());
            queryBuilder.must(regexName);
        }
        log.info("pageQueryWhoDrug query : {}" , queryBuilder.toString());
        return getResponseData(INDEX , TYPES_WD , query , queryBuilder, WdDd.class);
    }

    public static List<WdDd> regexDrugName(WhoDrugQuery query){
        MatchQueryBuilder version = QueryBuilders.matchQuery(F_V , query.getVersion());
        //MultiMatchQueryBuilder multiMatchQuery = QueryBuilders
        //        .multiMatchQuery(query.getRegexName() ,"drugName")
        //        .type(MultiMatchQueryBuilder.Type.BEST_FIELDS);

        MatchQueryBuilder regexName = QueryBuilders.matchQuery("drugName" , query.getRegexName());

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(version)
                .must(regexName);

        log.info("regexDrugName query : {}" , queryBuilder.toString());

        PageResult<WdDd> pageData = getResponseData(INDEX , TYPES_WD , query , queryBuilder , WdDd.class);
        return pageData.getData();
    }

    public static PageResult<MdLlt> pageQueryMedDra(MedDraQuery query){
        MatchQueryBuilder language = QueryBuilders.matchQuery(F_LAN , query.getLanguage());
        MatchQueryBuilder version = QueryBuilders.matchQuery(F_V , query.getVersion());
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(language)
                .must(version);

        if(StringKit.notBlank(query.getRegexName())){
            //MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(query.getRegexName() ,"lltName")
            //        .type(MultiMatchQueryBuilder.Type.BEST_FIELDS);

            MatchQueryBuilder regexName = QueryBuilders.matchQuery("lltName" , query.getRegexName());
            queryBuilder.must(regexName);
        }
        log.info("pageQueryMedDra query : {}" , queryBuilder.toString());
        return getResponseData(INDEX , TYPES_MD , query , queryBuilder, MdLlt.class);
    }

    public static List<MdLlt> regexLltName(MedDraQuery query){
        resetPage(query);

        MatchQueryBuilder version = QueryBuilders.matchQuery(F_V , query.getVersion());
        Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", "doc['lltCode'] == doc['ptCode']", new HashMap<>());
        ScriptQueryBuilder scriptQueryBuilder = QueryBuilders.scriptQuery(script);

        MatchQueryBuilder regexName = QueryBuilders.matchQuery("lltName" , query.getRegexName());
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(version)
                .must(regexName)
                .filter(scriptQueryBuilder);

        List<MdLlt> retData = new ArrayList<>();
        PageResult<MdLlt> pageData = getResponseData(INDEX , TYPES_MD , query , queryBuilder , MdLlt.class);

        log.info("regexLltName query : {}" , queryBuilder.toString());

        if(Kit.notEmptyCollection(pageData.getData())){
            retData.addAll(pageData.getData());
        }
        queryBuilder = QueryBuilders.boolQuery()
                .must(version)
                .must(regexName);

        log.info("regexLltName query : {}" , queryBuilder.toString());
        resetPage(query);

        pageData = getResponseData(INDEX , TYPES_MD , query , queryBuilder , MdLlt.class);
        if(Kit.notEmptyCollection(pageData.getData())){
            retData.addAll(pageData.getData());
        }
        return retData;
    }

    private static void resetPage(BaseQuery query){
        query.setPageNumber(1);
        query.setPageSize(100);
    }

    */
}
